home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / TR2LATEX / c / subs (.txt) next >
LaTeX Document  |  1992-04-27  |  20KB  |  753 lines

  1. ** tr2latex - troff to LaTeX converter
  2. ** $Id: subs.c,v 2.2 1992/04/27 15:13:26 Christian_Engel Dist krischan $
  3. ** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel
  4. ** Module: subs.c
  5. ** These subroutines do (in general) small things for the translator.
  6. ** They appear in alphabetical order and their names are unique in the
  7. ** first six characters.
  8. #include    "setups.h"
  9. #include    "protos.h"
  10. #include    "simil.h"
  11. #include    "greek.h"
  12. #include    "flip.h"
  13. #include    "forbid.h"
  14. #include    "maths.h"
  15. #include    "macros.h"
  16. extern def_count;
  17. extern mydef_count;
  18. /* compile-time counting of elements */
  19. int GRK_count = (sizeof(GRK_list)/sizeof(GRK_list[0]));
  20. int sim_count = (sizeof(sim_list)/sizeof(sim_list[0]));
  21. int flip_count = (sizeof(flip_list)/sizeof(flip_list[0]));
  22. int forbd_count = (sizeof(forbid)/sizeof(forbid[0]));
  23. int mathcom_count = (sizeof(math)/sizeof(struct math_equiv));
  24. int macro_count = (sizeof(macro)/sizeof(struct macro_table));
  25. ** alternate fonts (manual macro)
  26. char *alternate (char *pin, char *pout, char *w)
  27.     int which = 1;
  28.     char font[MAXWORD], font1[MAXWORD], font2[MAXWORD],
  29.          ww[MAXWORD], tmp[MAXWORD];
  30.     tmp[0] = EOS;
  31.     switch (w[1]) {
  32.     case 'R':    strcpy (font1,"\\rm"); break;
  33.     case 'I':    strcpy (font1,"\\it"); break;
  34.     case 'B':    strcpy (font1,"\\bf"); break;
  35.     switch (w[2]) {
  36.     case 'R':    strcpy (font2,"\\rm"); break;
  37.     case 'I':    strcpy (font2,"\\it"); break;
  38.     case 'B':    strcpy (font2,"\\bf"); break;
  39.     strcpy (font, font1);
  40.     while (*pin != '\n' && *pin != EOS) {
  41.         pin += get_arg (pin, ww, 1);
  42.         if (which == 1) {
  43.             sprintf(tmp,"{%s %s}", font1, ww);
  44.             which = 2;
  45.         else {
  46.             sprintf (tmp,"{%s %s}", font2, ww);
  47.             which = 1;
  48.         pout = strapp (pout, tmp);
  49.         while (*pin == ' ' || *pin == '\t')
  50.             pin++;
  51.     return (pout);
  52. ** check if w is in the GREEK list
  53. int CAP_GREEK (char *w)
  54.     int i;
  55.     for (i = 0; i < GRK_count; i++) {
  56.         if (strcmp (GRK_list[i], w) == 0)
  57.             return (1);
  58.     return (-1);
  59. ** translate table
  60. ** arguments:
  61. **  pin
  62. **  pout
  63. **    offset    amount to offset pin
  64. char *do_table (char *pin, char *pout, int *offset)
  65.     char w [MAXWORD], ww [MAXWORD], format [MAXWORD], tmp [MAXWORD];
  66.     char *ptr;
  67.     int i, len, columns=0;
  68.     int tab = '\t';                        /* default tab */
  69.     tmp[0] = EOS;
  70.     ptr = pin;                            /* remember where we started */
  71.     len = get_line (pin, w, 0);
  72.     if (w [strlen (w) - 1] == ';') {    /* options */
  73.         pin += len;
  74.         if (strncmp (w, "tab", 3) == 0)    /* get the tab charecter */
  75.             tab = w[4];        /* expect something like tab(&); */
  76.         pin = skip_line(pin);
  77.     while (*pin != EOS) {                /* get the LAST format line */
  78.         len = get_line (pin, w, 0);
  79.         if (w[strlen (w) - 1] != '.')    /* not a format line */
  80.             break;
  81.         pin += len;
  82.         for (i = 0; i < len - 1; i++) {
  83.             if (isspace (w[i]))
  84.                 continue;
  85.             if (w[i] == 'l')
  86.                 format[columns] = 'l';
  87.             else if (w[i] == 'r')
  88.                 format[columns] = 'r';
  89.             else
  90.                 format[columns] = 'c';
  91.             columns++;
  92.     if (columns == 0) {
  93.         fprintf (stderr, "Sorry, I cannot do tables without a format line\n\
  94. Doing plain translation of table, lines will be commented\n\
  95. You need to fix it yourself\n");
  96.         while (*pin != EOS) {
  97.             (void) getword (pin, w);
  98.             if (strcmp (w,".TE") ==  0) {
  99.                 pin += 4;
  100.                 break;
  101.             pin += get_line (pin, w, 1);
  102.             *pout++ = '%';
  103.             pout = strapp (pout, w);
  104.             pout = strapp (pout, "\n");
  105.             pin++;        /* skip the \n */
  106.         *offset = pin - ptr;
  107.         return (pout);
  108.     format[columns] = EOS;
  109.     sprintf (tmp, "\\par\n\\begin{tabular}{%s}\n",format);
  110.     pout = strapp (pout, tmp);
  111.     while (*pin != EOS) {
  112.         for (i = 0; i < columns - 1; i++) {
  113.             (void) getword (pin, w);
  114.             if (i == 0 && (strcmp (w, "\n") == 0 || strcmp (w, "_") == 0)) {
  115.                 pin++;
  116.                 i--;
  117.                 continue;
  118.             if (strcmp (w, ".TE") == 0) {
  119.                 pin += 4;
  120.                 if (i == 0) {
  121.                     pout -= 3;    /* take back the \\ and the \n */
  122.                     *pout = EOS;
  123.                 }
  124.                 pout = strapp(pout,"\n\\end{tabular}\n\\par\n");
  125.                 *offset = pin - ptr;
  126.                 return (pout);
  127.             pin += get_table_entry(pin,w,tab);
  128.             pin ++;        /* skip tab */
  129.             troff_tex(w,ww,0,1);
  130.             sprintf(tmp,"%s & ",ww);
  131.             pout = strapp(pout,tmp);
  132.         (void) getword (pin,w);
  133.         if (strcmp(w,".TE") == 0) {
  134.             fprintf(stderr,"Oops! I goofed. I told I you I am not very good at tables\nI've encountered an unexpected end for the table\n\
  135. You need to fix it yourself\n");
  136.             pin += 4;
  137.             pout = strapp(pout,"\\end{tabular}\n\\par\n");
  138.             *offset = pin - ptr;
  139.             return(pout);
  140.         pin += get_table_entry(pin,w,'\n');
  141.         pin++;        /* skip tab */
  142.         troff_tex(w,ww,0,1);
  143.         pout = strapp (pout, ww);
  144.         pout = strapp (pout, "\\\\\n");
  145.     fprintf (stderr, "Oops! I goofed. I told I you I am not very good at tables\n\
  146. File ended and I haven't finished the table!\n\
  147. You need to fix it yourself\n");
  148.     *offset = pin - ptr;
  149.     pout = strapp (pout, "\\end{tabular}\n\\par\n");
  150.     return (pout);
  151. ** end current environment
  152. char *end_env (char *pout)
  153.     if (IP_stat) {
  154.         IP_stat = 0;
  155.         pout = strapp (pout, "\\end{IPlist}");
  156.     if (QP_stat) {
  157.         QP_stat = 0;
  158.         pout = strapp (pout, "\\end{quotation}");
  159.     if (TP_stat) {
  160.         TP_stat = 0;
  161.         pout = strapp (pout, "\\end{TPlist}");
  162.     return(pout);
  163. ** set flag for current environment
  164. void envoke_stat (int par)
  165.     switch(par) {
  166.     case 2:
  167.         IP_stat = 1;
  168.         break;
  169.     case 3:
  170.         TP_stat = 1;
  171.         break;
  172.     case 4:
  173.         QP_stat = 1;
  174.         break;
  175.     default:
  176.         break;
  177. ** do the flipping
  178. char * flip (char *pout, char *w)
  179.     int lb=0, rb=0;
  180.     char ww[MAXWORD], tmp[MAXWORD];
  181.     ww[0] = EOS;
  182.     tmp[0] = EOS;
  183.     pout--;
  184.     while (isspace (*pout))
  185.         pout--;
  186.     while (1) {
  187.         if (*pout == '{') {
  188.             lb++;
  189.             if (lb > rb)
  190.                 break;
  191.         if (*pout == '}')
  192.             rb++;
  193.         if (rb == 0) {
  194.             if (! isspace (*pout) && *pout != '$') {
  195.                 pout--;
  196.                 continue;
  197.             else
  198.                 break;
  199.         pout--;
  200.         if (lb == rb && lb != 0)
  201.             break;
  202.     pout++;
  203.     if (*pout == '\\') {
  204.         pout++;
  205.         (void) getword (pout, tmp);
  206.         sprintf (ww, "\\%s", tmp);
  207.         pout--;
  208.     else if (*pout == '{')
  209.         (void) get_brace_arg (pout, ww);
  210.     else
  211.         (void) getword (pout, ww);
  212.     *pout = EOS;
  213.     sprintf (tmp,"\\%s %s", w, ww);
  214.     pout = strapp (pout, tmp);
  215.     return (pout);
  216. ** take care of things like x hat under
  217. char * flip_twice (char *pout, char *w, char *ww)
  218.     int lb=0, rb=0;
  219.     char tmp1[MAXWORD], tmp2[MAXWORD];
  220.     tmp1[0] = EOS;        tmp2[0] = EOS;
  221.     pout--;
  222.     while (*pout == ' ' || *pout == '\t' || *pout == '\n')
  223.         pout--;
  224.     while (1) {
  225.         if (*pout == '{') {
  226.             lb++;
  227.             if (lb > rb)
  228.                 break;
  229.         if (*pout == '}')
  230.             rb++;
  231.         if (rb == 0) {
  232.             if (! isspace (*pout) && *pout != '$') {
  233.                 pout--;
  234.                 continue;
  235.             else
  236.                 break;
  237.         pout--;
  238.         if (lb == rb && lb != 0)
  239.             break;
  240.     pout++;
  241.     if (*pout == '\\') {
  242.         pout++;
  243.         (void) getword(pout,tmp2);
  244.         sprintf(tmp1,"\\%s",tmp2);
  245.         pout--;
  246.     else if (*pout == '{')
  247.         (void) get_brace_arg(pout,tmp1);
  248.     else
  249.         (void) getword(pout,tmp1);
  250.     *pout = EOS;
  251.     sprintf(tmp2,"\\%s{\\%s %s}",w,ww,tmp1);
  252.     pout = strapp(pout,tmp2);
  253.     return(pout);
  254. ** get argument
  255. ** arguments:
  256. **  rec=1 means recursive 
  257. int    get_arg (register char *pin, char *w, int rec)
  258.     int c,len,i;
  259.     char ww[MAXWORD];
  260.     int delim;
  261.     len=0;
  262.     while ((c = *pin) == ' ' || c == '\t') {    /* skip spaces and tabs */
  263.         pin++;
  264.         len++;
  265.     i=0;
  266.     if (*pin == '{' || *pin == '\"') {
  267.         if (*pin == '{')
  268.             delim = '}';
  269.         else
  270.             delim = '\"';
  271.         pin++;
  272.         len++;
  273.         while ((c = *pin++) != EOS && c != delim && i < MAXWORD) {
  274.             if (c == ' ' && delim == '\"')
  275.                 ww[i++] = '\\';
  276.             ww[i++] = (char)c;
  277.             len++;
  278.         len++;
  279.     else {
  280.         while ((c = *pin++) != EOS && !isspace(c)
  281.                /* && c != '$' && c != '}' */ && i < MAXWORD) {
  282.             if (math_mode && c == '~')
  283.                 break;
  284.             ww[i++] = (char)c;
  285.             len++;
  286.     ww[i] = EOS;
  287.     if (rec == 1)                /* check if recursion is required */
  288.         troff_tex(ww,w,1,1);
  289.     else
  290.         strcpy(w,ww);
  291.     return(len);
  292. ** get all arguments
  293. ** arguments:
  294. **  rec=1 means recursive
  295. int    get_allargs (register char *pin, char ***ppw, int rec)
  296.     int c, i;
  297.     static char *ww [MAXARGS];
  298.     char w [MAXWORD], *instart;
  299.     int nww;
  300.     int delim;
  301.     instart = pin;
  302.     for (nww = 0; ; nww++) {
  303.         while ((c = *pin) == ' ' || c == '\t')    /* skip spaces and tabs */
  304.             pin++;
  305.         if (c == '\n') {
  306.             pin++;
  307.             ww [nww] = EOS;
  308.             break;
  309.         ww [nww] = pin;
  310.         i=0;
  311.         if (*pin == '{' || *pin == '\"') {
  312.             if (*pin == '{')
  313.                 delim = '}';
  314.             else
  315.                 delim = '\"';
  316.             ww [nww] = ++pin;
  317.             while ((c = *pin++) != EOS && c != delim && i < MAXWORD)
  318.                 /* EMPTY */
  319.                 ;
  320.             pin [-1] = EOS;
  321.         else {
  322.             while ((c = *pin++) != EOS && !isspace(c)
  323.                    /* && c != '$' && c != '}' */ && i < MAXWORD) {
  324.                 if (math_mode && c == '~')
  325.                     break;
  326.             pin [-1] = EOS;
  327.             if (c == '\n') {
  328.                 ww [nww + 1] = EOS;
  329.                 break;
  330.     if (rec == 1) {                /* check if recursion is required */
  331.         for (i = 0; ww [i]; i++) {
  332.             if (ww [i] && *ww [i]) {
  333.                 troff_tex (ww [i], w, 1, 1);
  334.                 if (strcmp (ww [i], w) != 0)
  335.                     ww [i] = strsave (w);
  336.     *ppw = ww;
  337.     return (pin - instart);
  338. ** get argument surrounded by braces
  339. void get_brace_arg (char *buf, char *w)
  340.     int c,i, lb=0, rb=0;
  341.     i=0;
  342.     while ((c = *buf++) != EOS) {
  343.         w[i++] = (char)c;
  344.         if (c == '{')    lb++;
  345.         if (c == '}')    rb++;
  346.         if (lb == rb)    break;
  347.     w[i] = EOS;
  348. ** get "define" or .de word
  349. ** arguments:
  350. **  pin    delimited by space only
  351. **  w      delimited by space only
  352. int get_defword (char *pin, char *w, int *illegal)
  353.     int c,i;
  354.     *illegal = 0;
  355.     for (i=0; (c = *pin++) != EOS && !isspace (c) && i < MAXWORD; i++) {
  356.         w[i] = (char)c;
  357.         if (isalpha(c) == 0)
  358.             *illegal = 1;    /* illegal TeX macro */ 
  359.     w[i] = EOS;
  360.     if (*illegal == 0 && is_forbid(w) >= 0)
  361.         *illegal=1;
  362.     return(i);
  363. ** get the rest of the line
  364. ** arguments:
  365. **  rec=1 means recursion is required
  366. int get_line (char *pin, char *w, int rec)
  367.     int c,i,len;
  368.     char ww[MAXLINE];
  369.     i=0;
  370.     len=0;
  371.     while ((c = *pin++) != EOS && c != '\n' && len < MAXLINE) {
  372.         ww[i++] = (char)c;
  373.         len++;
  374.     ww[i] = EOS;
  375.     if (rec == 1)
  376.         troff_tex(ww,w,0,1);
  377.     else
  378.         strcpy(w,ww);
  379.     return(len);
  380. ** get multi-line argument
  381. int get_multi_line (char *pin, char *w)
  382.     int len=0,l=0,lines=0;
  383.     char tmp[MAXWORD];
  384.     int c1,c2;
  385.     w[0] = EOS;    tmp[0] = EOS;
  386.     while (*pin != EOS) {
  387.         c1 = *pin;
  388.         c2 = *++pin;
  389.         --pin;
  390.         if (c1 == '.' && isupper(c2))
  391.             break; 
  392.         lines++;
  393.         if (lines > 1)
  394.             strcat(w," \\\\\n");
  395.         l = get_line(pin,tmp,1);
  396.         strcat(w,tmp);
  397.         len += l+1;
  398.         pin += l+1;
  399.     len--;
  400.     pin--;
  401.     return(len);
  402. ** get the macro substitution
  403. int get_mydef (char *pin, char *w)
  404.     int c1,c2,l,len;
  405.     char tmp[MAXWORD];
  406.     tmp[0] = EOS;
  407.     len=1;
  408.     while (*pin != EOS) {
  409.         c1 = *pin;
  410.         c2 = *++pin;
  411.         --pin;
  412.         if (c1 == '.' && c2 == '.')
  413.             break; 
  414.         l = get_line(pin,tmp,1);
  415.         strcat(w,tmp);
  416.         len += l+1;
  417.         pin += l+1;
  418.     return(len);
  419. ** get N lines
  420. int get_N_lines (char *pin, char *w, int N)
  421.     int len=0,l=0,lines=0;
  422.     char tmp[MAXWORD];
  423.     w[0] = EOS;    tmp[0] = EOS;
  424.     while (*pin != EOS && lines < N) {
  425.         lines++;
  426.         if (lines > 1)
  427.             strcat(w," \\\\\n");
  428.         l = get_line(pin,tmp,1);
  429.         strcat(w,tmp);
  430.         len += l+1;
  431.         pin += l+1;
  432.     len--;
  433.     pin--;
  434.     return(len);
  435. ** get text surrounded by quotes in math mode
  436. int get_no_math (char *pin, char *w)
  437.     int c,i,len;
  438.     len = 0;
  439.     for (i=0; (c = *pin++) != EOS && c != '\"' && i < MAXWORD; i++) {
  440.         if (c == '{' || c == '}') {
  441.             w[i] = '\\';
  442.             w[++i] = (char)c;
  443.         else
  444.             w[i] = (char)c;
  445.         len++;
  446.     w[i] = EOS;
  447.     return(len);
  448. ** get the denominator of over
  449. char *get_over_arg (char *pin, char *ww)
  450.     char w[MAXWORD], tmp1[MAXWORD], tmp2[MAXWORD];
  451.     int len;
  452.     w[0] = EOS;
  453.     tmp1[0] = EOS;
  454.     tmp2[0] = EOS;
  455.     pin += getword (pin,tmp1);        /* read first word */
  456.     pin += skip_white (pin);
  457.     len = getword (pin, tmp2);        /* read second word */
  458.     strcat(w,tmp1);    strcat(w," ");
  459.     /* as long as there is a sup or sub read the next two words */
  460.     while (strcmp (tmp2, "sub") == 0 || strcmp (tmp2, "sup") == 0) {
  461.         pin += len;
  462.         strcat (w, tmp2);
  463.         strcat (w, " ");
  464.         pin += skip_white (pin);
  465.         pin += getword (pin, tmp1);
  466.         strcat (w, tmp1);
  467.         strcat (w, " ");
  468.         pin += skip_white (pin);
  469.         len = getword (pin, tmp2);
  470.     troff_tex (w, ww, 0, 1);
  471.     return (pin);
  472. ** get reference
  473. int get_ref (char *pin, char *w)
  474.     int len=0, l=0, lines=0;
  475.     char tmp[MAXWORD];
  476.     w[0] = EOS;    tmp[0] = EOS;
  477.     while (*pin != EOS) {
  478.         if (*pin == '\n')
  479.             break;
  480.         (void) getword(pin,tmp);
  481.         if (tmp[0] == '.' && isupper(tmp[1])) {
  482.             /* these commands don't cause a break in reference */
  483.             if (strcmp (tmp, ".R") != 0 && strcmp (tmp, ".I") != 0
  484.                 && strcmp(tmp,".B") != 0)
  485.                 break; 
  486.         else if (tmp[0] == '.' && !(isupper(tmp[1]))) {
  487.             /* these commands don't cause a break in reference */
  488.             if (strcmp (tmp, ".br") != 0 && strcmp (tmp, ".bp") != 0)
  489.                 break; 
  490.         l = get_line (pin, tmp, 1);
  491.         lines++;
  492.         if (lines > 1)
  493.             strcat (w, " ");
  494.         strcat (w, tmp);
  495.         len += l+1;
  496.         pin += l+1;
  497.     len--;
  498.     pin--;
  499.     return (len);
  500. void get_size (char *ww, struct measure *PARAMETER)
  501.     int sign=0, units=0;
  502.     float value;
  503.     if (ww[0] == EOS) {
  504.         if (PARAMETER->def_value == 0) {
  505.             PARAMETER->value = PARAMETER->old_value;
  506.             strcpy(PARAMETER->units,PARAMETER->old_units);
  507.         else {
  508.             PARAMETER->value = PARAMETER->def_value;
  509.             strcpy(PARAMETER->units,PARAMETER->def_units);
  510.     else {
  511.         PARAMETER->old_value = PARAMETER->value;
  512.         strcpy (PARAMETER->old_units, PARAMETER->units);
  513.         parse_units (ww, &sign, &units, &value);
  514.         if (units == 'p')
  515.             strcpy (PARAMETER->units, "pt");
  516.         else if (units == 'i')
  517.             strcpy (PARAMETER->units, "in");
  518.         else if (units == 'c')
  519.             strcpy (PARAMETER->units, "cm");
  520.         else if (units == 'm')
  521.             strcpy (PARAMETER->units, "em");
  522.         else if (units == 'n') {
  523.             value = .5*value;    /* n is about half the width of m */
  524.             strcpy (PARAMETER->units, "em");
  525.         else if (units == 'v')
  526.             strcpy(PARAMETER->units,"ex");
  527.         else if (units == 0) {
  528.             if (sign == 0 || PARAMETER->old_units[0] == EOS)
  529.                 strcpy(PARAMETER->units,PARAMETER->def_units);
  530.             else
  531.                 strcpy(PARAMETER->units,PARAMETER->old_units);
  532.         else {
  533.             fprintf(stderr,"unknown units %c, using default units\n", units);
  534.             strcpy(PARAMETER->units,PARAMETER->def_units);
  535.         if (sign == 0)
  536.             PARAMETER->value = value;
  537.         else
  538.             PARAMETER->value = PARAMETER->old_value + sign*value;
  539. ** get the rest of the line -- Nelson Beebe
  540. ** arguments:
  541. **  rec=1 means recursion is required
  542. int get_string (char *pin, char *w, int rec)
  543.     register int c,i,len;
  544.     char ww[MAXLINE];
  545.     register char *start;
  546.     if (*pin != '\"')
  547.         return(get_line(pin,w,rec));
  548.     start = pin;                /* remember start so we can find len */
  549.     i=0;
  550.     pin++;                        /* point past initial quote */
  551.     while ((c = *pin++) != EOS && c != '\"' && c != '\n' && i < MAXLINE)
  552.         ww[i++] = (char)c;
  553.     ww[i] = EOS;
  554.     if (c != '\n')                /* flush remainder of line */
  555.         while ((c = *pin++) != '\n')
  556.         /* EMPTY */
  557.     len = pin - start - 1;        /* count only up to NL, not past */
  558.     if (rec == 1)
  559.         troff_tex(ww,w,0,1);
  560.     else
  561.         strcpy(w,ww);
  562.     return(len);
  563. ** get the argument for sub and sup
  564. int get_sub_arg (char *pin, char *w)
  565.     int c,len,i;
  566.     char ww[MAXWORD], tmp[MAXWORD];
  567.     len=0;    tmp[0] = EOS;
  568.     while ((c = *pin) == ' ' || c == '\t') {
  569.         pin++;
  570.         len++;
  571.     i=0;
  572.     while ((c = *pin++) != EOS && c != ' ' && c != '\t' && c != '\n'
  573.            && c != '$' && c != '}' && c != '~' && i < MAXWORD) {
  574.         ww[i++] = (char)c;
  575.         len++;
  576.     ww[i] = EOS;
  577.     if (strcmp(ww,"roman") == 0  || strcmp(ww,"bold") == 0
  578.         || strcmp(w,"italic") == 0) {
  579.         (void) get_arg(pin,tmp,0);
  580.         sprintf(ww,"%s%c%s",ww,c,tmp);
  581.         len += strlen(tmp)+1;
  582.     troff_tex(ww,w,0,1);        /* recursive */
  583.     return(len);
  584. int    get_table_entry (char *pin, char *w, int tab)
  585.     int c, i=0;
  586.     for (i=0; (c = *pin++) != EOS && c != tab && i < MAXWORD; i++)
  587.         w[i] = (char)c;
  588.     w[i] = EOS;
  589.     return(i);
  590. ** get characters till the next space
  591. int get_till_space (char *pin, char *w)
  592.     int c,i;
  593.     for (i=0; (c = *pin++) != EOS && c != ' ' && c != '\n'
  594.          && c != '\t' && i < MAXWORD; i++)
  595.         w[i] = (char)c;
  596.     w[i] = EOS;
  597.     return(i);
  598. ** get the define substitution
  599. int getdef (char *pin, char *ww)
  600.     int c,i,len;
  601.     int def_delim;
  602.     char w[MAXWORD];
  603.     def_delim = *pin++;        /* take first character as delimiter */
  604.     len=1;
  605.     i=0;
  606.     while ((c = *pin++) != EOS && c != def_delim && i < MAXWORD) {
  607.         len++;
  608.         w[i++] = (char)c;
  609.     w[i] = EOS;
  610.     len++;
  611.     if (c != def_delim) {
  612.         fprintf(stderr,
  613.                 "WARNING: missing right delimiter in define, define=%s\n",w);
  614.         len--;
  615.     troff_tex(w,ww,0,1);        /* now translate the substitution */
  616.     return(len);
  617. ** get an alphanumeric word (dot also)
  618. int getword (char *pin, char *w)
  619.     int c,i;
  620.     for (i=0; (c = *pin++) != EOS
  621.          && (isalpha(c) || isdigit(c) || c == '.') && i < MAXWORD; i++)
  622.         w[i] = (char)c;
  623.     if (i == 0 && c != EOS)
  624.         w[i++] = (char)c;
  625.     w[i] = EOS;
  626.     return(i);
  627. ** change GREEK to Greek
  628. void GR_to_Greek (char *w, char *ww)
  629.     *ww++ = '\\';
  630.     *ww++ = *w;
  631.     while(*++w != EOS)
  632.         *ww++ = tolower(*w);
  633.     *ww = EOS;
  634. ** check if w was defined by the user
  635. int is_def (char *w)
  636.     int i;
  637.     for (i=0; i < def_count; i++) {
  638.         if (strcmp(def[i].def_macro,w) == 0)
  639.             return(i);
  640.     return(-1);
  641. ** check if w is in the flip list
  642. int is_flip (char *w)
  643.     int i;
  644.     for (i=0; i < flip_count; i++) {
  645.         if (strcmp(flip_list[i],w) == 0)
  646.             return(i);
  647.     return(-1);
  648. ** check if w is one of those sacred macros
  649. int is_forbid (char *w)
  650.     int i;
  651.     for (i=0; i < forbd_count; i++) {
  652.         if (strcmp(forbid[i],w) == 0)
  653.             return(i);
  654.     return(-1);
  655. ** check if w has a simple correspondence in TeX
  656. int is_mathcom (char *w, char *ww)
  657.     int i;
  658.     for (i = 0; i < mathcom_count; i++)
  659.         if (strcmp (math[i].troff_symb, w) == 0) {
  660.             strcpy (ww, math[i].tex_symb);
  661.             return (i);
  662.     return (-1);
  663. ** check if w is user-defined macro
  664. int is_mydef (char *w)
  665.     int i;
  666.     for (i=0; i < mydef_count; i++) {
  667.         if (strcmp(mydef[i].def_macro,w) == 0)
  668.             return(i);
  669.     return(-1);
  670. ** check if w is a macro or plain troff command
  671. int is_troff_mac (char *w, char *ww, int *arg, int *par)
  672.     int i;
  673.     for (i=0; i < macro_count; i++)
  674.         if (strcmp(macro[i].troff_mac,w) == 0) {
  675.             strcpy(ww,macro[i].tex_mac);
  676.             *arg = macro[i].arg;
  677.             *par = macro[i].macpar;
  678.             return(i);
  679.     return(-1);
  680. void parse_units (char *ww, int *sign, int *units, float *value)
  681.     int len, k=0, i;
  682.     char tmp[MAXWORD];
  683.     len = strlen(ww);
  684.     if (ww[0] == '-')
  685.         *sign = -1;
  686.     else if (ww[0] == '+')
  687.         *sign = 1;
  688.     if (*sign != 0)
  689.         k++;
  690.     i=0;
  691.     while (k < len) {
  692.         if (isdigit(ww[k]) || ww[k] == '.')
  693.             tmp[i++] = ww[k++];
  694.         else
  695.             break;
  696.     tmp[i] = EOS;
  697.     sscanf(tmp,"%f",value);
  698.     i=0;
  699.     if (k < len) {
  700.         *units = ww[k++];
  701.         if (k < len)
  702.             fprintf(stderr, "Suspect problem in parsing %s, unit used is %c\n",
  703.                     ww, *units);
  704. ** check if w is in the similar list
  705. int similar (char *w)
  706.     int i;
  707.     for (i=0; i < sim_count ; i++) {
  708.         if (strcmp(sim_list[i],w) == 0)
  709.             return(1);
  710.     return(-1);
  711. ** ignore the rest of the line
  712. char * skip_line (char *pin)
  713.     while (*pin != '\n' && *pin != EOS)
  714.         pin++;
  715.     if (*pin == EOS)
  716.         return(pin);
  717.     else
  718.         return(++pin);
  719. ** skip white space
  720. int skip_white (char *pin)
  721.     int c,len=0;
  722.     while ((c = *pin++) == ' ' || c == '\t' || c == '\n')
  723.         len++;    
  724.     return(len);
  725. ** copy tail[] to s[], return ptr to terminal EOS in s[]
  726. char * strapp (register char *s, register char *tail)
  727.     while ((*s++ = *tail++) != 0)
  728. #ifdef DEBUG
  729.         if (debug_o)
  730.             putchar (s[-1]);
  731. #else
  732.         /*EMPTY*/
  733. #endif
  734.     return (s-1);            /* pointer to EOS at end of s[] */
  735. ** copy input to buffer, buffer holds only MAXLEN characters
  736. void tmpbuf (FILE *in, char *buffer)
  737.     int c;
  738.     unsigned int l=0;
  739.     while (l++ < MAXLEN && (c = getc(in)) != EOF)
  740.         *buffer++ = (char) c;
  741.     if (l >= MAXLEN) {
  742.         fprintf (stderr,"Sorry: document is too large\n");
  743.         exit(-1);
  744.     *buffer = EOS;
  745. ** save a string by allocating space
  746. char *strsave (char *s)
  747.     char *res;
  748.     if ((res = malloc (strlen (s) + 1)) == NULL) {
  749.         fprintf (stderr, "strsave: Can't allocate %d bytes\n", strlen(s) + 1);
  750.         errexit (errno);
  751.     strcpy (res, s);
  752.     return (res);
  753.